<?php

/**
 * Menashop
 *
 * LICENSE
 *
 * This source file is subject to the license that is bundled
 * with this project in the file LICENSE.txt
 *
 * @category   Menashop
 * @package    Menashop_Content
 * @subpackage Measures
 * @copyright  Copyright (c) 2011 Menashop UA Inc. (http://www.menashop.com.ua)
 * @license    LICENSE.txt
 * @version    1.0.0
 * @since      File available since Release 1.0.0
 */

/**
 * The SAX handler for measures
 * 
 * @category   Menashop
 * @package    Menashop_Content
 * @subpackage Measures
 * @copyright  Copyright (c) 2011 Menashop UA Inc. (http://www.menashop.com.ua)
 * @license    LICENSE.txt
 */
class Menashop_Content_Measures
{

    /**
     * The data model for a measure
     * @var Admin_Model_Measure
     */
    protected $_measureModel = null;

    /**
     * The model for a measure translation model
     * @var Admin_Model_MeasureTranslation
     */
    protected $_measureTranslationModel = null;

    /**
     * Current language
     * @var integer
     */
    protected $_languageId = null;

    /**
     * IDs of languages
     * @var array 
     */
    protected $_languages = null;

    /**
     * Measure
     * @var array
     */
    protected $_measure = null;

    /**
     * Measure translations
     * @var array 
     */
    protected $_measureTranslations = null;

    /**
     * The flag for a tag 'Desctiption'
     * @var integer 
     */
    protected $_inDescription = 0;

    /**
     * The flag for a tag 'Name'
     * @var integer 
     */
    protected $_inName = 0;

    /**
     * The flag for a tag 'Sign'
     * @var integer 
     */
    protected $_inSign = 0;

    /**
     * The counter for measures
     * @var integer 
     */
    protected $_totalMeasures = 0;

    /**
     * The counter for inserted measures
     * @var integer 
     */
    protected $_totalMeasuresInserted = 0;

    /**
     * The counter for updated measures
     * @var integer 
     */
    protected $_totalMeasuresUpdated = 0;

    /**
     * The counter for measure translations
     * @var integer 
     */
    protected $_totalMeasureTranslations = 0;

    /**
     * The counter for inserted measure translations
     * @var integer 
     */
    protected $_totalMeasureTranslationsInserted = 0;

    /**
     * The counter for updated measure translations
     * @var integer 
     */
    protected $_totalMeasureTranslationsUpdated = 0;

    /**
     * Initialize the SAX handler for measures
     * @param array $languages 
     */
    public function __construct($languages)
    {
        $this->_measureModel = new Admin_Model_Measure();
        $this->_measureTranslationModel = new Admin_Model_MeasureTranslation();
        $this->_languages = $languages;
    }

    /**
     * Process the start of an element in XML
     * @param obejct $parser
     * @param string $tag
     * @param array $attributes 
     */
    public function startElement($parser, $tag, $attributes)
    {
        if ('Measure' == $tag) {
            $this->_measure = array();
            $this->_measure['content_id'] = $attributes['ID'];
            $this->_measureTranslations = array();
        } elseif ('Name' == $tag) {
            // check a measure translation for the current language
            if (in_array($attributes['langid'], $this->_languages)) {
                // check a measure translation
                if (!isset($this->_measureTranslations[$attributes['langid']])) {
                    // create a new measure translation
                    $measureTranslation = array();
                    $measureTranslation['language_id'] = $attributes['langid'];
                    $this->_measureTranslations[$attributes['langid']] = &$measureTranslation;
                    $this->_totalMeasureTranslations++;
                }
                $this->_languageId = $attributes['langid'];
                $this->_inName = 1;
            }
        } elseif ('Description' == $tag) {
            // check a measure translation for the current language
            if (in_array($attributes['langid'], $this->_languages)) {
                // check a measure translation
                if (!isset($this->_measureTranslations[$attributes['langid']])) {
                    // create a new measure translation
                    $measureTranslation = array();
                    $measureTranslation['language_id'] = $attributes['langid'];
                    $this->_measureTranslations[$attributes['langid']] = &$measureTranslation;
                    $this->_totalMeasureTranslations++;
                }
                $this->_languageId = $attributes['langid'];
                $this->_inDescription = 1;
            }
        } elseif ('Sign' == $tag) {
            // check a measure translation for the current language
            if (isset($attributes['langid']) && in_array($attributes['langid'], $this->_languages)) {
                // check a measure translation
                if (!isset($this->_measureTranslations[$attributes['langid']])) {
                    // create a new measure translation
                    $measureTranslation = array();
                    $measureTranslation['language_id'] = $attributes['langid'];
                    $this->_measureTranslations[$attributes['langid']] = &$measureTranslation;
                    $this->_totalMeasureTranslations++;
                }
                $this->_languageId = $attributes['langid'];
                $this->_inSign = 1;
            }
        }
    }

    /**
     * Process the end of an element in XML
     * @param object $parser
     * @param string $tag 
     */
    public function endElement($parser, $tag)
    {
        if ('Measure' == $tag) {
            // find a measure in the database
            $measureId = $this->_measureModel->findIdByContentId($this->_measure['content_id']);
            if ($measureId) {
                $this->_totalMeasuresUpdated++;
            } else {
                // insert the measure
                $measureId = $this->_measureModel->save($this->_measure);
                $this->_totalMeasuresInserted++;
            }
            foreach ($this->_measureTranslations as $languageId => $measureTranslation) {
                $measureTranslationId = $this->_measureTranslationModel->findIdByMeasureAndLanguage($measureId, $languageId);
                if ($measureTranslationId) {
                    // update the measure translation
                    $measureTranslation['id'] = $measureTranslationId;
                    $this->_totalMeasureTranslationsUpdated++;
                } else {
                    // insert the measure translation
                    $this->_totalMeasureTranslationsInserted++;
                }
                $measureTranslation['measure_id'] = $measureId;
                $this->_measureTranslationModel->save($measureTranslation);
            }
            $this->_totalMeasures++;
        } elseif ('Name' == $tag) {
            $this->_inName = 0;
        } elseif ('Description' == $tag) {
            $this->_inDescription = 0;
        } elseif ('Sign' == $tag) {
            $this->_inSign = 0;
        }
    }

    /**
     * Process characters in XML
     * @param object $parser
     * @param string $data 
     */
    public function characterData($parser, $data)
    {
        if ($this->_inName) {
            // check measure translation for the current language
            if (isset($this->_measureTranslations[$this->_languageId])) {
                $measureTranslation = &$this->_measureTranslations[$this->_languageId];
                if (isset($measureTranslation['name'])) {
                    $measureTranslation['name'] .= trim($data);
                } else {
                    $measureTranslation['name'] = trim($data);
                }
            }
        } elseif ($this->_inDescription) {
            // check measure translation for the current language
            if (isset($this->_measureTranslations[$this->_languageId])) {
                $measureTranslation = &$this->_measureTranslations[$this->_languageId];
                if (isset($measureTranslation['description'])) {
                    $measureTranslation['description'] .= trim($data);
                } else {
                    $measureTranslation['description'] = trim($data);
                }
            }
        } elseif ($this->_inSign) {
            // check measure translation for the current language
            if (isset($this->_measureTranslations[$this->_languageId])) {
                $measureTranslation = &$this->_measureTranslations[$this->_languageId];
                if (isset($measureTranslation['sign'])) {
                    $measureTranslation['sign'] .= trim($data);
                } else {
                    $measureTranslation['sign'] = trim($data);
                }
            }
        }
    }

    /**
     * Get the report about a parsing
     * @return string 
     */
    public function getReport()
    {
        $report = "$this->_totalMeasures measures in XML,";
        $report .= " $this->_totalMeasuresInserted inserted,";
        $report .= " $this->_totalMeasuresUpdated updated\n";
        $report .= "$this->_totalMeasureTranslations measure translations in XML,";
        $report .= " $this->_totalMeasureTranslationsInserted inserted,";
        $report .= " $this->_totalMeasureTranslationsUpdated updated";
        return $report;
    }

}

